﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Net.Http;
using System.Threading;

namespace U01_boke
{
    /// <summary>
    /// 接口管理
    /// </summary>
    public class Api : ApiBase
    {
        #region 留言管理
        /// <summary>
        /// 获取所有留言信息
        /// api_code:api_message_list_get
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Message> GetMessages()
        {
            var (sql, _) = SQLBuilder.Message_All_SQL();
            SqlDataReader reader = SqlHelper.ExecuteDataReader(sql);
            return SqlHelper.ExecuteDataReaderList<Message>(sql);
        }
        /// <summary>
        /// 获取留言分页信息
        /// api_code:api_message_paged_get
        /// </summary>
        /// <returns></returns>
        public PagedingResult GetMessagesPaged(int pageIndex = 1, int pageSize = 10)
        {
            var (sql_page, param) = SQLBuilder.Message_Paged_SQL(pageIndex, pageSize);
            IEnumerable<MessageViewer> viewers = SqlHelper.ExecuteDataReaderList<MessageViewer>(sql_page, param);
            //获取总记录数
            var (sql_all, _) = SQLBuilder.Message_All_Count_SQL();
            int count = Convert.ToInt32(SqlHelper.ExecuteScalar(sql_all));
            return PagedingResult.Parse(viewers, count, pageIndex);
        }

        /// <summary>
        /// 新增一条留言
        /// api_code:api_message_add_post
        /// </summary>
        /// <param name="content">评论内容</param>
        public OperationResult AddMessage(string content)
        {
            base.VerificationString(content, 500, "不要沉默，大声说出来。", "少说点废话行吗，内存很宝贵的。");
            //回车/n,转html元素
            var new_content = content.Replace("\n", "</br>");

            string IP = IPHelper.GetCurrentIP();
            var visitor = CacheManage.Get<VisitorViewer>(IP);
            if (visitor == null)
                visitor = RecordIP(IP);
            var (sql, param) = SQLBuilder.Message_Insert_SQL(new_content, visitor.ID);
            SqlHelper.ExecuteNonQuery(sql, param);
            return new OperationResult("评论成功");
        }

        #endregion

        #region IP管理

        #endregion

        #region 缓存管理
        /// <summary>
        /// 清楚所有缓存数据
        /// api_code:api_cache_clear_all_post
        /// </summary>
        public OperationResult CacheClearAll(string SecretKey)
        {
            string secret = AppSettingsManage.GetValue(AppSetting.CacheKey);
            if (secret.Equals(SecretKey))
            {
                CacheManage.RemoveAll();
                return new OperationResult("-rm success");
            }
            return new OperationResult("secret key Incorrect！", 201);
        }
        #endregion

        #region 静态外部调用方法
        /// <summary>
        /// 记录IP信息,生成游客信息
        /// </summary>
        public static VisitorViewer RecordIP(string ip)
        {
            //验证IP是否存在，存在更新访问时间，不存在则添加记录
            var (ip_sql, ip_param) = SQLBuilder.IP_Single_SQL(ip);
            SysIP sys_ip = SqlHelper.ExecuteDataReader<SysIP>(ip_sql, ip_param);

            if (sys_ip == null)
            {
                var (ip_add_sql, ip_add_param) = SQLBuilder.IP_Insert_SQL(ip);
                SqlHelper.ExecuteNonQuery(ip_add_sql, ip_add_param);
                //查询出新增的数据
                sys_ip = SqlHelper.ExecuteDataReader<SysIP>(ip_sql, ip_param);

                //开启线程去执行调取三方IP数据
                ThreadManager.TaskStart(() =>
                {
                    int ip_id = sys_ip.ID;
                    Dictionary<string, object> dic = null;
                    //最多读取三次信息，三次都是失败，则放弃
                    for (int i = 0; i < 3; i++)
                    {
                        dic = GetIpInfo(ip);
                        if (dic != null) break;
                    }
                    var (ip_up_sql, ip_up_param) = SQLBuilder.IP_Update_Info_SQL(dic, ip_id);
                    SqlHelper.ExecuteNonQuery(ip_up_sql, ip_up_param);
                });
            }
            else
            {
                //更新ip访问时间
                var (ip_up_sql, ip_up_param) = SQLBuilder.IP_Update_Time_SQL(ip);
                SqlHelper.ExecuteNonQuery(ip_up_sql, ip_up_param);
            }

            //根据IP查询游客信息
            var (v_sql, v_param) = SQLBuilder.Visitor_Single_SQL(sys_ip.ID);
            Visitor visitor = SqlHelper.ExecuteDataReader<Visitor>(v_sql, v_param);
            //游客不存在则根据IP生成游客信息
            if (visitor == null)
            {
                var (v_add_sql, v_add_param) = SQLBuilder.Visitor_Insert_SQL(sys_ip.ID);
                SqlHelper.ExecuteNonQuery(v_add_sql, v_add_param);
                visitor = SqlHelper.ExecuteDataReader<Visitor>(v_sql, v_param);
            }

            //缓存访客数据
            VisitorViewer viewer = new VisitorViewer()
            {
                ID = visitor.ID,
                Name = visitor.Name,
                IPID = sys_ip.ID,
                IP = sys_ip.IP
            };
            return viewer;
        }

        /// <summary>
        /// 调用三方接口获取IP基本信息
        /// </summary>
        private static Dictionary<string, object> GetIpInfo(string ip)
        {
            HttpClient client = new HttpClient();
            var task = client.GetAsync("http://ip.taobao.com/service/getIpInfo.php?ip=" + ip);
            task.Result.EnsureSuccessStatusCode();
            HttpResponseMessage response = task.Result;
            var result = response.Content.ReadAsStringAsync();
            string responseBodyAsText = result.Result;

            var code = SerializerFactory.Deserialize<Dictionary<string, dynamic>>(responseBodyAsText);
            if (code.ContainsKey("code") && code["code"] == 0)
            {
                return code["data"];
            }
            return null;
        }
        #endregion
    }

    /// <summary>
    /// 接口基类
    /// </summary>
    public class ApiBase
    {
        #region 字符串验证
        /// <summary>
        /// 字符串验证，非空验证
        /// </summary>
        /// <param name="value">字符串</param>
        /// <param name="message">异常消息</param>
        public void VerificationString(string value, string message)
        {
            if (string.IsNullOrEmpty(value))
            {
                throw new ResultException(message);
            }
        }
        /// <summary>
        /// 字符串验证，非空长度验证
        /// </summary>
        /// <param name="value">字符串</param>
        /// <param name="len">最大长度</param>
        /// <param name="message">异常消息，按验证顺序读取</param>
        public void VerificationString(string value, int len, params string[] message)
        {
            if (string.IsNullOrEmpty(value))
            {
                throw new ResultException(message[0]);
            }
            if (value.Length >= len)
            {
                throw new ResultException(message[1]);
            }
        }
        #endregion
    }
}